﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using ComLib.ComFun;
using System.IO.MemoryMappedFiles;
using System.Threading;
using AForge.Imaging.Filters;
using ComLib.ConfigService;
using ProcessConfig;
using System.Drawing.Imaging;
using LogLib;
using KAImage.AlgorAction;
using System.Diagnostics;

namespace DetectProcessing
{
    /// <summary>
    /// 待识别的源文件（图像等等）, 用于人脸算法输入参数
    /// </summary>
    public class RecogIn : IDisposable
    {
        public const string ShareMemoryFileName = "AforgeNewVideoFrame";

        public const string MutexName = "MemoryMapMutex";
    
        public static long MemoryCapacity = 50000000;

        public static Size CheckSize = new Size(427, 512);

        public static ResizeBilinear Resizefilter = null;

        private static BufferManage _bufferManage;

        static RecogIn()
        {
            _bufferManage = BufferManage.Instance;
            Resizefilter = new ResizeBilinear(CheckSize.Width, CheckSize.Height);
        }

        private BaseResizeFilter _resizefilter = null;

        /// <summary>
        /// 原图存储字节数组的有效长度
        /// </summary>
        private int _sourceDataLength = 0;
        public int SourceDataLength
        {
            get
            {
                return _sourceDataLength;
            }
        }

        /// <summary>
        /// 原始图像数据
        /// </summary>
        private byte[] _sourceImageData = null;
        public byte[] SourceImageData
        {
            get
            {
                return _sourceImageData;
            }
            private set
            {
                _sourceImageData = value;
            }
        }

        /// <summary>
        /// 用于加载并转化bytes字节数组的内存流
        /// </summary>
        private MemoryStream _stream = null;

        /// <summary>
        /// 检测图像（经过压缩）数据
        /// </summary>
        private byte[] _checkImageData = null;
        public byte[] CheckImageData
        {
            get
            {
                return _checkImageData;
            }
            set
            {
                _checkImageData = value;
            }
        }

        /// <summary>
        /// 原始图像
        /// </summary>
        private Bitmap _sourceImage = null;
        public Bitmap SourceImage
        {
            get
            {
                return _sourceImage;
            }
            private set
            {
                _sourceImage = value;
            }
        }

        //文件名
        private string _fileName = "";
        public string FileName
        {
            get { return _fileName; }
        }

        public bool IsEmpty
        {
            get 
            {
                return _sourceImageData == null || _sourceImage == null || _sourceImageData.Length == 0;
            }
        }

        public RecogIn(string fileName)
        {
            _fileName = fileName;
            _resizefilter = new ResizeBilinear(Configs.PhoSize.CheckSize.Width, Configs.PhoSize.CheckSize.Height); 
        }

        public void ToBitmap()
        {
            try
            {
                _stream = new MemoryStream(_sourceImageData, 0, _sourceDataLength);
                _sourceImage = new Bitmap(_stream);
            }
            catch (ArgumentNullException ex)
            {
                throw ex;
            }
            catch (ArgumentException ex)
            {
                throw ex;
            }          
        }

        public void ReleaseMemoryStream()
        {
            if (_stream != null)
            {
                _stream.Close();
                _stream.Dispose();
                _stream = null;
            }
        }

        public void SetBufferData(byte[] bufferData, int length)
        {
            _sourceDataLength = length;
            _sourceImageData = bufferData;
           ToBitmap();
            SetCheckImageData();
        }

        public void ReturnBuffer()
        {
            if (_sourceImageData != null && _sourceImageData.Length > 0)
            {
                _bufferManage.ReturnBuffer(_sourceImageData);
            }               
        }

        public bool SaveSourceBitmap(string path, ImageFormat format)
        {
            if (_sourceImage == null)
            {
                Log.WriteAsync("原图Bitmap为空.");
                return false;
            }
            try
            {
                _sourceImage.Save(path, format);
                return true;
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
                return false;
            }         
        }

        public void AdjustImage()
        {
            CustomActions a = new CustomActions(_sourceImage);
            //a.WorkImageUpdated += browser.WorkImage_Updated;
            Stopwatch sw = new Stopwatch();
            sw.Start();
            a.Execute();
            Bitmap destSource = a.DestImage;
            sw.Stop();
            Log.WriteAsync("耗时:" + sw.ElapsedMilliseconds.ToString());
            if (destSource != null)
            {
                SetData(destSource);
            }         
        }

        private void SetCheckImageData()
        {
            Bitmap checkImage = _resizefilter.Apply(_sourceImage);
            _checkImageData = IPCCom.Bitmap2ByteArray_BMP(checkImage);
            checkImage.Dispose();
            checkImage = null;
        }

        private void SetData(Bitmap source)
        {
            Dispose();
            _sourceImage = source;        
            //_sourceImageData = IPCCom.Bitmap2ByteArray_BMP(source);
            _sourceImageData = _bufferManage.GetJPEGValues(source, out _sourceDataLength);
            SetCheckImageData();
        }

        public void LoadFromFile(string sourceFile)
        {
            try
            {
                ReturnBuffer();
                Dispose();
                _sourceImage = new Bitmap(sourceFile);
                _sourceImageData = _bufferManage.GetBMPValues(_sourceImage, out _sourceDataLength);
                SetCheckImageData();
                Log.WriteAsync($"照片数据变更为:{sourceFile}");
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
            }        
        }

        public void Dispose()
        {
            _sourceDataLength = 0;
            _sourceImageData = null;
            if (_sourceImage != null)
            {
                _sourceImage.Dispose();
                _sourceImage = null;
            }
            GC.Collect();
        }
    };
}
